package org.gitos.cloud.comet.tcp;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import org.gitos.cloud.domain.tcp.Bucket;
import org.gitos.cloud.domain.tcp.DeviceId;
import org.gitos.cloud.domain.tcp.Sequeue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * TcpDecoder
 * 负责分包和对象组装
 *
 * @author purely
 * @date 2015/12/4
 */
@Component
public class TcpDecoder extends ByteToMessageDecoder {
    private static final Logger log = LoggerFactory.getLogger(TcpDecoder.class);
    private static byte[] EMPTY_BYTEARRAY = new byte[0];

    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
//        parseObjectWithFlag(ctx, in, out);
        parseObjectWithLength(ctx, in, out);
    }

    private void parseObjectWithLength(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) {
        int readableBytes = in.readableBytes();
        //数据包不允许小于4字节
        if (readableBytes < Bucket.HEAD_LENGTH) {
            log.error("readableBytes < HEAD_LENGTH. that is {}. close.", readableBytes);
            ctx.pipeline().close();
            return;
        }

        Bucket bucket = new Bucket(ctx);
        short length = in.readShort();
        bucket.setLength(length);

        bucket.setMagic(in.readShort());
        bucket.setCrc(in.readShort());
        bucket.setVersion(in.readByte());
        bucket.setCmd(in.readShort());

        byte[] deviceId = new byte[DeviceId.LENGTH];
        in.readBytes(deviceId);
        bucket.setDeviceId(DeviceId.instance(deviceId));

        byte[] dataSeq = new byte[Sequeue.LENGTH];
        in.readBytes(dataSeq);
        bucket.setDataSeq(Sequeue.instance(dataSeq));

        byte[] ackSeq = new byte[Sequeue.LENGTH];
        in.readBytes(ackSeq);
        bucket.setDataSeq(Sequeue.instance(ackSeq));
        byte[] content = new byte[length - Bucket.HEAD_LENGTH];
        in.readBytes(content);
        bucket.setContent(content);
        log.info("bucket contetn:{}", content);
        out.add(bucket);
    }


}
